package com.chrissy.music.system.service.impl;

import cn.hutool.core.text.CharSequenceUtil;
import com.chrissy.music.common.cache.TokenStoreCache;
import com.chrissy.music.common.constant.Constants;
import com.chrissy.music.common.context.AuthenticationContextHolder;
import com.chrissy.music.common.entity.LoginUser;
import com.chrissy.music.common.exception.ApiException;
import com.chrissy.music.common.request.SysCaptchaRequest;
import com.chrissy.music.common.request.SysLoginRequest;
import com.chrissy.music.common.utils.TokenUtils;
import com.chrissy.music.system.service.SysCaptchaService;
import com.chrissy.music.system.service.SysLoginService;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Service;

/**
 * @author Johnson
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class SysLoginServiceImpl implements SysLoginService {

    private final SysCaptchaService sysCaptchaService;

    private final AuthenticationManager authenticationManager;

    private final TokenUtils tokenUtils;

    private final TokenStoreCache tokenStoreCache;

    @Override
    public String login(SysLoginRequest sysLoginRequest) {
        SysCaptchaRequest sysCaptchaRequest = new SysCaptchaRequest();
        sysCaptchaRequest.setCode(sysLoginRequest.getCode());
        sysCaptchaRequest.setUuid(sysLoginRequest.getUuid());
        boolean flag = sysCaptchaService.validate(sysCaptchaRequest);
        if (!flag) {
            throw new ApiException(Constants.FAILED, "验证码错误");
        }
        Authentication authentication;
        try {
            UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(sysLoginRequest.getUsername(), sysLoginRequest.getPassword());
            AuthenticationContextHolder.setContext(authenticationToken);
            // 该方法会去调用UserDetailsServiceImpl.loadUserByUsername
            authentication = authenticationManager.authenticate(authenticationToken);
        } catch (BadCredentialsException e) {
            throw new ApiException(500, "用户名或密码错误");
        }
        LoginUser user = (LoginUser) authentication.getPrincipal();
        return tokenUtils.createToken(user);
    }

    @Override
    public void logout(HttpServletRequest request) {
        String accessToken = request.getHeader("Authorization");
        if (CharSequenceUtil.isBlank(accessToken)) {
            accessToken = request.getParameter("access_token");
        }

        // 删除用户信息
        tokenStoreCache.deleteUser(accessToken);

    }
}
